home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 681 / term / source.lha / Packet.c < prev    next >
C/C++ Source or Header  |  1992-05-09  |  23KB  |  1,025 lines

  1. /*
  2. **    $Id: Packet.c,v 1.3 92/04/07 20:13:11 olsen Sta Locker: olsen $
  3. **    $Revision: 1.3 $
  4. **    $Date: 92/04/07 20:13:11 $
  5. **
  6. **    Support routines for the `packet window'
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* A custom message structure. */
  15.  
  16. struct PacketMessage
  17. {
  18.     struct Message     VanillaMessage;
  19.     LONG         Line;
  20. };
  21.  
  22.     /* Some private data required to handle both the window,
  23.      * the editing functions and the command history buffer.
  24.      */
  25.  
  26. STATIC struct Hook         PacketHook;
  27. STATIC UBYTE             PacketWorkBuffer[256];
  28. STATIC struct StringInfo    *PacketInfo;
  29.  
  30. STATIC struct MsgPort        *PacketPort;
  31.  
  32. STATIC LONG             PacketLine;
  33. STATIC LONG             PacketCount;
  34. STATIC STRPTR             PacketString = NULL;
  35. STATIC LONG             PacketX = -1,PacketY = -1,PacketWidth = -1,PacketHeight = -1;
  36.  
  37. STATIC BYTE             HasList = FALSE;
  38.  
  39.     /* Gadget IDs */
  40.  
  41. enum    {    GAD_STRING, GAD_LIST };
  42.  
  43.     /* The menu to attach to the packet window. */
  44.  
  45. enum    {    MEN_LOADHISTORY=1,MEN_SAVEHISTORY,MEN_CLEARHISTORY,MEN_OTHERWINDOW,MEN_QUITPANEL };
  46.  
  47. STATIC struct NewMenu NewPacketMenu[] =
  48. {
  49.     { NM_TITLE, NULL,         0 , 0, 0, (APTR)0},
  50.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_LOADHISTORY},
  51.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_SAVEHISTORY},
  52.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  53.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_CLEARHISTORY},
  54.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  55.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_OTHERWINDOW},
  56.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  57.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_QUITPANEL},
  58.     { NM_END, 0,             0 , 0, 0, (APTR)0}
  59. };
  60.  
  61.     /* SendPacketMsg(LONG Line):
  62.      *
  63.      *    Tell the main process to display a certain line.
  64.      */
  65.  
  66. STATIC VOID __regargs
  67. SendPacketMsg(LONG Line)
  68. {
  69.     struct PacketMessage *Msg;
  70.  
  71.     if(Msg = (struct PacketMessage *)AllocVec(sizeof(struct PacketMessage),MEMF_PUBLIC|MEMF_CLEAR))
  72.     {
  73.         Msg -> VanillaMessage . mn_Length    = sizeof(struct PacketMessage);
  74.         Msg -> Line                = Line;
  75.  
  76.         PutMsg(PacketPort,Msg);
  77.     }
  78. }
  79.  
  80.     /* ClearPacketHistory():
  81.      *
  82.      *    Release the command history.
  83.      */
  84.  
  85. VOID
  86. ClearPacketHistory()
  87. {
  88.     struct Node *SomeNode,*NextNode;
  89.  
  90.     if(HasList)
  91.     {
  92.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  93.             GTLV_Labels,    ~0,
  94.         TAG_DONE);
  95.     }
  96.  
  97.     SomeNode = PacketHistoryList . lh_Head;
  98.  
  99.     while(SomeNode -> ln_Succ)
  100.     {
  101.         NextNode = SomeNode -> ln_Succ;
  102.  
  103.         Remove(SomeNode);
  104.  
  105.         FreeVec(SomeNode);
  106.  
  107.         SomeNode = NextNode;
  108.     }
  109.  
  110.     PacketCount = PacketLine = 0;
  111.  
  112.     if(HasList)
  113.     {
  114.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  115.             GTLV_Labels,    &PacketHistoryList,
  116.         TAG_DONE);
  117.     }
  118.  
  119.     PacketString = NULL;
  120. }
  121.  
  122.     /* DeletePacketWindow():
  123.      *
  124.      *    Delete the packet window and release the command
  125.      *    history.
  126.      */
  127.  
  128. VOID
  129. DeletePacketWindow()
  130. {
  131.     if(PacketWindow)
  132.     {
  133.         PacketWindow -> Flags |= WFLG_RMBTRAP;
  134.  
  135.         ClearMenuStrip(PacketWindow);
  136.  
  137.         if(PacketGadgetList)
  138.             RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  139.  
  140.         PacketX        = PacketWindow -> LeftEdge;
  141.         PacketY        = PacketWindow -> TopEdge;
  142.  
  143.         PacketWidth    = PacketWindow -> Width;
  144.         PacketHeight    = PacketWindow -> Height;
  145.  
  146.         CloseWindow(PacketWindow);
  147.  
  148.         PacketWindow = NULL;
  149.     }
  150.  
  151.     if(PacketGadgetList)
  152.     {
  153.         FreeGadgets(PacketGadgetList);
  154.  
  155.         PacketGadgetList = NULL;
  156.     }
  157.  
  158.     HasList = FALSE;
  159.  
  160.     if(PacketPort)
  161.     {
  162.         struct Message *Message;
  163.  
  164.         while(Message = GetMsg(PacketPort))
  165.             FreeVec(Message);
  166.  
  167.         FreeVec(PacketPort);
  168.  
  169.         PacketPort = NULL;
  170.     }
  171.  
  172.     ClearPacketHistory();
  173.  
  174.     if(PacketMenu)
  175.     {
  176.         FreeMenus(PacketMenu);
  177.  
  178.         PacketMenu = NULL;
  179.     }
  180. }
  181.  
  182.     /* AddPacketHistory(UBYTE *Buffer):
  183.      *
  184.      *    Add a line to the packet window command history. This
  185.      *    works very much the same as the AddLine()-routine.
  186.      */
  187.  
  188. VOID
  189. AddPacketHistory(UBYTE *Buffer)
  190. {
  191.     struct Node *SomeNode;
  192.  
  193.     if(HasList)
  194.     {
  195.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  196.             GTLV_Labels,    ~0,
  197.         TAG_DONE);
  198.     }
  199.  
  200.     if(SomeNode = (struct Node *)AllocVec(sizeof(struct Node) + strlen(Buffer) + 1,MEMF_ANY|MEMF_CLEAR))
  201.     {
  202.         SomeNode -> ln_Name = (UBYTE *)(SomeNode + 1);
  203.  
  204.         strcpy(SomeNode -> ln_Name,Buffer);
  205.  
  206.         AddTail(&PacketHistoryList,SomeNode);
  207.  
  208.         PacketCount = ++PacketLine;
  209.     }
  210.  
  211.     if(HasList)
  212.     {
  213.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  214.             GTLV_Top,    PacketCount - 1,
  215.             GTLV_Labels,    &PacketHistoryList,
  216.         TAG_DONE);
  217.     }
  218. }
  219.  
  220.     /* CreateAllGadgets():
  221.      *
  222.      *    Create the packet string gadget.
  223.      */
  224.  
  225. STATIC struct Gadget *
  226. CreateAllGadgets(LONG Width,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  227. {
  228.     struct Gadget        *Gadget;
  229.     struct NewGadget     NewGadget;
  230.  
  231.     memset(&NewGadget,0,sizeof(struct NewGadget));
  232.  
  233.     if(Gadget = CreateContext(GadgetList))
  234.     {
  235.         WORD Rest = (PacketHeight - (29 + 2 * 2)) / 8;
  236.  
  237.         NewGadget . ng_Width        = Width - 26;
  238.         NewGadget . ng_Height        = 14;
  239.         NewGadget . ng_GadgetText    = NULL;
  240.         NewGadget . ng_TextAttr        = &DefaultFont;
  241.         NewGadget . ng_VisualInfo    = VisualInfo;
  242.         NewGadget . ng_GadgetID        = GAD_STRING;
  243.         NewGadget . ng_Flags        = 0;
  244.         NewGadget . ng_LeftEdge        = 6;
  245.         NewGadget . ng_TopEdge        = 1 + TopEdge;
  246.  
  247.         GadgetArray[GAD_STRING] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  248.             GTST_MaxChars,    256,
  249.             GTST_EditHook,    &PacketHook,
  250.             GA_TabCycle,    FALSE,
  251.         TAG_DONE);
  252.  
  253.             /* If the window is large enough to display the
  254.              * list, create the list view gadget.
  255.              */
  256.  
  257.         if(Rest > 0)
  258.         {
  259.             NewGadget . ng_Height        = 14 + 2 * 2 + 8 * Rest;
  260.             NewGadget . ng_GadgetID        = GAD_LIST;
  261.  
  262.             GadgetArray[GAD_LIST] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
  263.                 GTLV_ShowSelected,    GadgetArray[GAD_STRING],
  264.                 GTLV_Labels,        &PacketHistoryList,
  265.                 GTLV_Selected,        PacketCount,
  266.                 GTLV_Top,        PacketCount,
  267.             TAG_DONE);
  268.  
  269.             if(Gadget)
  270.                 HasList = TRUE;
  271.             else
  272.                 HasList = FALSE;
  273.         }
  274.         else
  275.             HasList = FALSE;
  276.     }
  277.  
  278.     return(Gadget);
  279. }
  280.  
  281.     /* CreatePacketWindow():
  282.      *
  283.      *    Open the packet window and allocate the command history
  284.      *    buffer.
  285.      */
  286.  
  287. BYTE
  288. CreatePacketWindow()
  289. {
  290.     LocalizeMenu(NewPacketMenu,MSG_PACKET_PROJECT_MEN);
  291.  
  292.     if(PacketPort = (struct MsgPort *)AllocVec(sizeof(struct MsgPort),MEMF_PUBLIC | MEMF_CLEAR))
  293.     {
  294.         if(PacketMenu = CreateMenus(NewPacketMenu,
  295.             GTMN_FrontPen, 0,
  296.         TAG_DONE))
  297.         {
  298.             if(LayoutMenus(PacketMenu,VisualInfo,
  299.                 GTMN_TextAttr,&DefaultFont,
  300.             TAG_DONE))
  301.             {
  302.                 if(PacketWidth == -1)
  303.                     PacketWidth = Screen -> Width;
  304.  
  305.                 if(PacketHeight == -1)
  306.                     PacketHeight = 29;
  307.  
  308.                 if(PacketX == -1 || (PacketX + PacketWidth > Screen -> Width))
  309.                 {
  310.                     PacketX = 0;
  311.  
  312.                     if(PacketX + PacketWidth > Screen -> Width)
  313.                         PacketWidth = Screen -> Width;
  314.                 }
  315.  
  316.                 if(PacketY == -1 || (PacketY + PacketHeight > Screen -> Height))
  317.                 {
  318.                     PacketY = Window -> TopEdge + Window -> Height;
  319.  
  320.                     if(PacketY + PacketHeight > Screen -> Height)
  321.                         PacketHeight = 29;
  322.                 }
  323.  
  324.                 if(CreateAllGadgets(PacketWidth,&PacketGadgetArray[0],&PacketGadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  325.                 {
  326.                     if(PacketWindow = OpenWindowTags(NULL,
  327.                         WA_Width,        PacketWidth,
  328.                         WA_Height,        PacketHeight,
  329.  
  330.                         WA_Left,        PacketX,
  331.                         WA_Top,            PacketY,
  332.  
  333.                         WA_Activate,        TRUE,
  334.                         WA_DragBar,        TRUE,
  335.                         WA_DepthGadget,        TRUE,
  336.                         WA_CloseGadget,        TRUE,
  337.                         WA_RMBTrap,        TRUE,
  338.                         WA_SizeGadget,        TRUE,
  339.                         WA_MinWidth,        80,
  340.                         WA_MinHeight,        29,
  341.                         WA_MaxWidth,        Screen -> Width,
  342.                         WA_MaxHeight,        Screen -> Height,
  343.                         WA_CustomScreen,    Screen,
  344.                         WA_NoCareRefresh,    TRUE,
  345.  
  346.                         WA_IDCMP,        STRINGIDCMP | LISTVIEWIDCMP | IDCMP_NEWSIZE | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS,
  347.  
  348.                         WA_Title,        LocaleString(MSG_GLOBAL_PACKET_WINDOW_TXT),
  349.                     TAG_DONE))
  350.                     {
  351.                         PacketPort -> mp_Flags        = PA_SIGNAL;
  352.                         PacketPort -> mp_SigBit        = PacketWindow -> UserPort -> mp_SigBit;
  353.                         PacketPort -> mp_SigTask    = PacketWindow -> UserPort -> mp_SigTask;
  354.  
  355.                         NewList(&PacketPort -> mp_MsgList);
  356.  
  357.                         PacketHook . h_Entry        = (APTR)PacketKey;
  358.                         PacketHook . h_SubEntry        = NULL;
  359.                         PacketHook . h_Data        = NULL;
  360.  
  361.                         PacketInfo = (struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo;
  362.  
  363.                         AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  364.                         RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  365.                         GT_RefreshWindow(PacketWindow,NULL);
  366.  
  367.                         SetMenuStrip(PacketWindow,PacketMenu);
  368.  
  369.                         PacketWindow -> Flags &= ~WFLG_RMBTRAP;
  370.  
  371.                         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  372.  
  373.                         return(TRUE);
  374.                     }
  375.                 }
  376.             }
  377.         }
  378.     }
  379.  
  380.     DeletePacketWindow();
  381.  
  382.     return(FALSE);
  383. }
  384.  
  385.     /* PacketKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
  386.      *
  387.      *    This is a string gadget editing call back routine
  388.      *    (a so-called `hook') which is to perform all the
  389.      *    line editing and command history actions supported
  390.      *    by the packet window.
  391.      */
  392.  
  393. VOID __saveds __asm
  394. PacketKey(register __a0 struct Hook *Hook,register __a1 ULONG *Msg,register __a2 struct SGWork *Work)
  395. {
  396.         /* Someone activated the string gadget and
  397.          * hit a key.
  398.          */
  399.  
  400.     if(Msg[0] == SGH_KEY)
  401.     {
  402.         if(Work -> IEvent -> ie_Qualifier & IEQUALIFIER_RCOMMAND)
  403.         {
  404.             if(Work -> Code == 'c')
  405.             {
  406.                 Work -> Actions &= ~SGA_USE;
  407.                 Work -> Actions |= SGA_BEEP;
  408.  
  409.                 if(Work -> PrevBuffer[0])
  410.                 {
  411.                     struct MsgPort *ReplyPort;
  412.  
  413.                     if(ReplyPort = CreateMsgPort())
  414.                     {
  415.                         struct Message ClipMessage;
  416.  
  417.                         ClipMessage . mn_Node . ln_Name    = Work -> PrevBuffer;
  418.                         ClipMessage . mn_ReplyPort    = ReplyPort;
  419.                         ClipMessage . mn_Length        = sizeof(struct Message);
  420.  
  421.                         PutMsg(ClipPort,&ClipMessage);
  422.  
  423.                         WaitPort(ReplyPort);
  424.  
  425.                         GetMsg(ReplyPort);
  426.  
  427.                         DeleteMsgPort(ReplyPort);
  428.  
  429.                         Work -> Actions &= ~SGA_BEEP;
  430.                     }
  431.                 }
  432.  
  433.                 return;
  434.             }
  435.  
  436.             if(Work -> Code == 'v')
  437.             {
  438.                 Work -> Actions &= ~SGA_USE;
  439.                 Work -> Actions |= SGA_BEEP;
  440.  
  441.                 if(!(Work -> Gadget -> Activation & GACT_LONGINT))
  442.                 {
  443.                     struct MsgPort *ReplyPort;
  444.  
  445.                     if(ReplyPort = CreateMsgPort())
  446.                     {
  447.                         STATIC UBYTE    Buffer[2048];
  448.                         struct Message    ClipMessage;
  449.  
  450.                         Buffer[0] = 0;
  451.  
  452.                         ClipMessage . mn_Node . ln_Name    = &Buffer[0];
  453.                         ClipMessage . mn_ReplyPort    = ReplyPort;
  454.                         ClipMessage . mn_Length        = sizeof(struct Message);
  455.  
  456.                         PutMsg(ClipPort,&ClipMessage);
  457.  
  458.                         WaitPort(ReplyPort);
  459.  
  460.                         GetMsg(ReplyPort);
  461.  
  462.                         DeleteMsgPort(ReplyPort);
  463.  
  464.                         if(Buffer[0])
  465.                         {
  466.                             WORD Len = strlen(Buffer);
  467.  
  468.                             while(Len > 0 && Work -> NumChars + Len > Work -> StringInfo -> MaxChars)
  469.                                 Len--;
  470.  
  471.                             if(Len > 0)
  472.                             {
  473.                                 STATIC UBYTE OtherBuffer[2048];
  474.  
  475.                                 Buffer[Len] = 0;
  476.  
  477.                                 if(Work -> StringInfo -> UndoBuffer)
  478.                                     strcpy(Work -> StringInfo -> UndoBuffer,Work -> PrevBuffer);
  479.  
  480.                                 Work -> StringInfo -> UndoPos = --Work -> BufferPos;
  481.  
  482.                                 if(Work -> BufferPos)
  483.                                     CopyMem(Work -> PrevBuffer,OtherBuffer,Work -> BufferPos);
  484.  
  485.                                 OtherBuffer[Work -> BufferPos] = 0;
  486.  
  487.                                 strcat(OtherBuffer,Buffer);
  488.  
  489.                                 strcat(OtherBuffer,&Work -> PrevBuffer[Work -> BufferPos]);
  490.  
  491.                                 strcpy(Work -> WorkBuffer,OtherBuffer);
  492.  
  493.                                 Work -> BufferPos += Len;
  494.                                 Work -> NumChars    += Len;
  495.  
  496.                                 Work -> Actions    |= SGA_USE;
  497.                                 Work -> EditOp     = EO_BIGCHANGE;
  498.  
  499.                                 Work -> Actions &= ~SGA_BEEP;
  500.                             }
  501.                         }
  502.                         else
  503.                             Work -> Actions &= ~SGA_BEEP;
  504.                     }
  505.                 }
  506.  
  507.                 return;
  508.             }
  509.         }
  510.  
  511.             /* Right-Amiga-key was pressed, release the
  512.              * string gadget so user may select a menu
  513.              * item.
  514.              */
  515.  
  516.         if((Work -> IEvent -> ie_Qualifier & AMIGARIGHT) && Work -> IEvent -> ie_Code < 96)
  517.         {
  518.             if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) && (Work -> IEvent -> ie_Code == KEYCODE_X || Work -> IEvent -> ie_Code == KEYCODE_Q))
  519.                 return;
  520.             else
  521.             {
  522.                 Work -> Actions |= (SGA_END|SGA_REUSE);
  523.                 Work -> Actions &= ~(SGA_USE|SGA_BEEP);
  524.  
  525.                 CommandWindow = Work -> GadgetInfo -> gi_Window;
  526.                 CommandGadget = Work -> Gadget;
  527.             }
  528.         }
  529.  
  530.             /* The user pressed the cursor-right key to
  531.              * move the cursor to the next word in the buffer.
  532.              */
  533.  
  534.         if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  535.         {
  536.             if(Work -> BufferPos != Work -> NumChars)
  537.             {
  538.                 WORD i,Position = -1;
  539.  
  540.                 for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
  541.                 {
  542.                     if(Work -> WorkBuffer[i] == ' ')
  543.                     {
  544.                         for( ; i < Work -> NumChars ; i++)
  545.                         {
  546.                             if(Work -> WorkBuffer[i] != ' ')
  547.                             {
  548.                                 Position = i;
  549.                                 break;
  550.                             }
  551.                         }
  552.  
  553.                         break;
  554.                     }
  555.                 }
  556.  
  557.                 if(Position != -1)
  558.                     Work -> BufferPos = Position;
  559.                 else
  560.                     Work -> BufferPos = Work -> NumChars;
  561.  
  562.                 Work -> EditOp = EO_MOVECURSOR;
  563.             }
  564.         }
  565.  
  566.             /* The user pressed the cursor-right key to
  567.              * move the cursor to the previous word in the buffer.
  568.              */
  569.  
  570.         if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  571.         {
  572.             if(Work -> BufferPos)
  573.             {
  574.                 WORD i,Position = -1;
  575.  
  576.                 for(i = Work -> BufferPos ; i >= 0 ; i--)
  577.                 {
  578.                     if(Work -> WorkBuffer[i] != ' ')
  579.                     {
  580.                         Position = i;
  581.                         break;
  582.                     }
  583.                 }
  584.  
  585.                 if(Position == -1)
  586.                     Position = 0;
  587.  
  588.                 if(Position)
  589.                 {
  590.                     i = Position;
  591.  
  592.                     Position = -1;
  593.  
  594.                     for( ; i >= 0 ; i--)
  595.                     {
  596.                         if(Work -> WorkBuffer[i] == ' ')
  597.                         {
  598.                             Position = i + 1;
  599.                             break;
  600.                         }
  601.                     }
  602.                 }
  603.  
  604.                 if(Position != -1)
  605.                     Work -> BufferPos = Position;
  606.                 else
  607.                     Work -> BufferPos = 0;
  608.  
  609.                 Work -> EditOp = EO_MOVECURSOR;
  610.             }
  611.         }
  612.  
  613.             /* The user pressed the cursor-up key to
  614.              * scroll through the command history.
  615.              */
  616.  
  617.         if(Work -> IEvent -> ie_Code == CURSORUP)
  618.         {
  619.                 /* Shift key: jump to first command
  620.                  * history entry.
  621.                  */
  622.  
  623.             if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  624.             {
  625.                 if(PacketLine)
  626.                     SendPacketMsg(0);
  627.             }
  628.             else
  629.             {
  630.                 if(PacketLine && PacketCount > 0)
  631.                     SendPacketMsg(PacketCount - 1);
  632.             }
  633.         }
  634.  
  635.             /* The user pressed the cursor-down key to
  636.              * scroll through the command history.
  637.              */
  638.  
  639.         if(Work -> IEvent -> ie_Code == CURSORDOWN)
  640.         {
  641.                 /* Shift key: jump to last command
  642.                  * history entry.
  643.                  */
  644.  
  645.             if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  646.             {
  647.                 if(PacketLine > 0)
  648.                     SendPacketMsg(PacketLine);
  649.             }
  650.             else
  651.             {
  652.                 if(PacketCount < PacketLine)
  653.                     SendPacketMsg(PacketCount + 1);
  654.             }
  655.         }
  656.     }
  657. }
  658.  
  659.     /* HandlePacket():
  660.      *
  661.      *    Process the input coming through the packet window.
  662.      */
  663.  
  664. BYTE
  665. HandlePacket()
  666. {
  667.     struct IntuiMessage    *Massage;
  668.     struct PacketMessage    *PacketMsg;
  669.     ULONG             Class,Code;
  670.     struct Gadget        *Gadget;
  671.     struct FileRequest    *FileRequest;
  672.     UBYTE             DummyBuffer[256];
  673.     BYTE             SwapWindow = FALSE;
  674.  
  675.         /* Are we already shut down? */
  676.  
  677.     if(PacketWindow)
  678.     {
  679.         BYTE Result = FALSE;
  680.  
  681.         if(Massage = (struct IntuiMessage *)GT_GetIMsg(PacketWindow -> UserPort))
  682.         {
  683.             Class    = Massage -> Class;
  684.             Code    = Massage -> Code;
  685.             Gadget    = (struct Gadget *)Massage -> IAddress;
  686.  
  687.             GT_ReplyIMsg(Massage);
  688.  
  689.                 /* Re-enable the string gadget if necessary. */
  690.  
  691.             if(Class == IDCMP_RAWKEY)
  692.                 if(Code == IECODE_UP_PREFIX|103 && CommandWindow == PacketWindow)
  693.                     ActivateGadget(CommandGadget,PacketWindow,NULL);
  694.  
  695.                 /* Handle the menu. */
  696.  
  697.             if(Class == IDCMP_MENUPICK)
  698.             {
  699.                 struct MenuItem *MenuItem;
  700.  
  701.                 while(Code != MENUNULL)
  702.                 {
  703.                     MenuItem = ItemAddress(PacketMenu,Code);
  704.  
  705.                     switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
  706.                     {
  707.                         case MEN_QUITPANEL:    Class = IDCMP_CLOSEWINDOW;
  708.                                     break;
  709.  
  710.                         case MEN_LOADHISTORY:    BlockWindows();
  711.  
  712.                                     if(FileRequest = GetFile(LocaleString(MSG_PACKET_LOAD_HISTORY_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT)))
  713.                                     {
  714.                                         if(GetFileSize(DummyBuffer))
  715.                                         {
  716.                                             BPTR SomeFile;
  717.  
  718.                                             if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  719.                                             {
  720.                                                 if(PacketLine)
  721.                                                 {
  722.                                                     switch(MyEasyRequest(Window,LocaleString(MSG_PACKET_PACKET_WINDOW_STILL_HOLDS_LINES_TXT),LocaleString(MSG_PACKET_DISCARD_APPEND_CANCEL_TXT),PacketLine))
  723.                                                     {
  724.                                                         case 1:    ClearPacketHistory();
  725.                                                             break;
  726.  
  727.                                                         case 2:    break;
  728.  
  729.                                                         case 0:    Close(SomeFile);
  730.                                                             SomeFile = NULL;
  731.                                                             break;
  732.                                                     }
  733.                                                 }
  734.  
  735.                                                 if(SomeFile)
  736.                                                 {
  737.                                                     WORD Len;
  738.  
  739.                                                     LineRead(NULL,NULL,NULL);
  740.  
  741.                                                     while(Len = LineRead(SomeFile,DummyBuffer,255))
  742.                                                     {
  743.                                                         DummyBuffer[Len - 1] = 0;
  744.  
  745.                                                         AddPacketHistory(DummyBuffer);
  746.                                                     }
  747.  
  748.                                                     Close(SomeFile);
  749.                                                 }
  750.                                             }
  751.                                         }
  752.                                     }
  753.  
  754.                                     ReleaseWindows();
  755.                                     break;
  756.  
  757.                         case MEN_SAVEHISTORY:    BlockWindows();
  758.  
  759.                                     if(!PacketLine)
  760.                                         MyEasyRequest(Window,LocaleString(MSG_PACKET_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  761.                                     else
  762.                                     {
  763.                                         if(FileRequest = GetFile(LocaleString(MSG_PACKET_SAVE_HISTORY_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT)))
  764.                                         {
  765.                                             BPTR SomeFile = NULL;
  766.  
  767.                                                 /* If the file we are about
  768.                                                  * to create already exists,
  769.                                                  * ask the user whether we are
  770.                                                  * to create, append or skip
  771.                                                  * the file.
  772.                                                  */
  773.  
  774.                                             if(GetFileSize(DummyBuffer))
  775.                                             {
  776.                                                 switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  777.                                                 {
  778.                                                     case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  779.                                                         break;
  780.  
  781.                                                     case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  782.                                                         {
  783.                                                             if(Seek(SomeFile,0,OFFSET_END) == -1)
  784.                                                             {
  785.                                                                 Close(SomeFile);
  786.  
  787.                                                                 SomeFile = NULL;
  788.                                                             }
  789.                                                         }
  790.                                                         break;
  791.                                                 }
  792.                                             }
  793.                                             else
  794.                                                 SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  795.  
  796.                                             if(!SomeFile)
  797.                                                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  798.                                             else
  799.                                             {
  800.                                                 struct Node *SomeNode;
  801.  
  802.                                                 SomeNode = PacketHistoryList . lh_Head;
  803.  
  804.                                                 while(SomeNode -> ln_Succ)
  805.                                                 {
  806.                                                     FPrintf(SomeFile,"%s\n",SomeNode -> ln_Name);
  807.  
  808.                                                     SomeNode = SomeNode -> ln_Succ;
  809.                                                 }
  810.  
  811.                                                 Close(SomeFile);
  812.                                             }
  813.  
  814.                                             FreeAslRequest(FileRequest);
  815.                                         }
  816.                                     }
  817.  
  818.                                     ReleaseWindows();
  819.  
  820.                                     break;
  821.  
  822.                         case MEN_CLEARHISTORY:  BlockWindows();
  823.  
  824.                                     ClearPacketHistory();
  825.  
  826.                                     ReleaseWindows();
  827.                                     break;
  828.  
  829.                         case MEN_OTHERWINDOW:    SwapWindow = TRUE;
  830.                                     break;
  831.  
  832.                         default:        break;
  833.                     }
  834.  
  835.                     Code = MenuItem -> NextSelect;
  836.                 }
  837.  
  838.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  839.             }
  840.  
  841.                 /* Shut down. */
  842.  
  843.             if(Class == IDCMP_CLOSEWINDOW)
  844.             {
  845.                 DeletePacketWindow();
  846.  
  847.                 return(FALSE);
  848.             }
  849.  
  850.                 /* Activate the string gadget as well. */
  851.  
  852.             if(Class == IDCMP_ACTIVEWINDOW)
  853.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  854.  
  855.             if(Class == IDCMP_NEWSIZE)
  856.             {
  857.                 PacketWindow -> Flags |= WFLG_RMBTRAP;
  858.  
  859.                 strcpy(DummyBuffer,PacketInfo -> Buffer);
  860.  
  861.                 RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  862.  
  863.                 FreeGadgets(PacketGadgetList);
  864.  
  865.                 PacketGadgetList = NULL;
  866.  
  867.                 SetAPen(PacketWindow -> RPort,0);
  868.                 RectFill(PacketWindow -> RPort,PacketWindow -> BorderLeft,PacketWindow -> BorderTop,PacketWindow -> Width - PacketWindow -> BorderRight,PacketWindow -> Height - PacketWindow -> BorderBottom);
  869.                 RefreshWindowFrame(PacketWindow);
  870.  
  871.                 PacketHeight    = PacketWindow -> Height;
  872.                 PacketWidth    = PacketWindow -> Width;
  873.  
  874.                 if(CreateAllGadgets(PacketWindow -> Width,&PacketGadgetArray[0],&PacketGadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  875.                 {
  876.                     PacketInfo = (struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo;
  877.  
  878.                     strcpy(PacketInfo -> Buffer,DummyBuffer);
  879.  
  880.                     AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  881.                     RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  882.                     GT_RefreshWindow(PacketWindow,NULL);
  883.  
  884.                     PacketWindow -> Flags &= ~WFLG_RMBTRAP;
  885.  
  886.                     ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  887.                 }
  888.                 else
  889.                 {
  890.                     DeletePacketWindow();
  891.  
  892.                     return(FALSE);
  893.                 }
  894.             }
  895.  
  896.             if(Class == IDCMP_MOUSEBUTTONS)
  897.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  898.  
  899.                 /* User has entered a string. */
  900.  
  901.             if(Class == IDCMP_GADGETUP)
  902.             {
  903.                 switch(Gadget -> GadgetID)
  904.                 {
  905.                     case GAD_STRING:        /* Just pressed Right-Amiga? */
  906.  
  907.                                     /* Is there anything in the buffer at all? */
  908.  
  909.                                 if(PacketInfo -> Buffer[0])
  910.                                 {
  911.                                     strcpy(DummyBuffer,PacketInfo -> Buffer);
  912.  
  913.                                     if(PacketString)
  914.                                     {
  915.                                         if(strcmp(PacketString,DummyBuffer))
  916.                                             AddPacketHistory(DummyBuffer);
  917.  
  918.                                         PacketString = NULL;
  919.                                     }
  920.                                     else
  921.                                         AddPacketHistory(DummyBuffer);
  922.  
  923.                                         /* Convert alien IBM characters. */
  924.  
  925.                                     if(Config . Font == FONT_IBM)
  926.                                     {
  927.                                         WORD i;
  928.                                         UBYTE Char;
  929.  
  930.                                         for(i = 0 ; i < strlen(DummyBuffer) ; i++)
  931.                                         {
  932.                                             if(Char = IBMConversion[DummyBuffer[i]])
  933.                                                 DummyBuffer[i] = Char;
  934.                                         }
  935.                                     }
  936.  
  937.                                         /* Execute the command. */
  938.  
  939.                                     SerialCommand(DummyBuffer);
  940.                                 }
  941.  
  942.                                     /* Clear the packet window string
  943.                                      * gadget.
  944.                                      */
  945.  
  946.                                 GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  947.                                     GTST_String,    "",
  948.                                 TAG_DONE);
  949.  
  950.                                     /* Send a terminating `CR'. */
  951.  
  952.                                 switch(Config . SendCR)
  953.                                 {
  954.                                     case CR_IGNORE:    break;
  955.  
  956.                                     case CR_ASCR:    SerWrite("\r",1);
  957.                                             break;
  958.  
  959.                                     case CR_ASCRLF:    SerWrite("\r\n",2);
  960.                                             break;
  961.                                 }
  962.  
  963.                                     /* Re-activate the string gadget. */
  964.  
  965.                                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  966.  
  967.                                 break;
  968.  
  969.                     case GAD_LIST:        ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  970.                                 break;
  971.                 }
  972.             }
  973.  
  974.             if(SwapWindow)
  975.                 BumpWindow(Window);
  976.  
  977.             Result = TRUE;
  978.         }
  979.  
  980.         if(PacketMsg = (struct PacketMessage *)GetMsg(PacketPort))
  981.         {
  982.             struct Node *Node;
  983.  
  984.             Result = TRUE;
  985.  
  986.             if(Node = GetListNode(PacketMsg -> Line,&PacketHistoryList))
  987.             {
  988.                 PacketString = Node -> ln_Name;
  989.  
  990.                 if(HasList)
  991.                 {
  992.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  993.                         GTLV_Selected,    PacketMsg -> Line,
  994.                         GTLV_Top,    PacketMsg -> Line,
  995.                     TAG_DONE);
  996.                 }
  997.                 else
  998.                 {
  999.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  1000.                         GTST_String,    Node -> ln_Name,
  1001.                     TAG_DONE);
  1002.                 }
  1003.             }
  1004.             else
  1005.             {
  1006.                 PacketString = NULL;
  1007.  
  1008.                 GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  1009.                     GTST_String,    "",
  1010.                 TAG_DONE);
  1011.             }
  1012.  
  1013.             PacketCount = PacketMsg -> Line;
  1014.  
  1015.             FreeVec(PacketMsg);
  1016.  
  1017.             ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  1018.         }
  1019.  
  1020.         return(Result);
  1021.     }
  1022.  
  1023.     return(FALSE);
  1024. }
  1025.